#include <stdint.h>

#include "lvgl.h"
#include "lv_demo.h"

#include "co_printf.h"
#include "os_timer.h"

#include "driver_system.h"
#include "driver_timer.h"
#include "driver_display.h"
#include "driver_touchpad.h"
#include "timer.h"
#include "driver_cst816.h"



static os_timer_t lv_schedule_timer;

static lv_disp_draw_buf_t disp_buf;

static lv_disp_drv_t *last_disp = NULL;

// this function is called in DMA interrupt
static void my_disp_flush_done(void)
{
//    lv_disp_flush_ready(last_disp);
    last_disp = NULL;
}

static void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
	
	
	#if 1
    if(last_disp != NULL) {
        display_wait_transfer_done();
    }
    last_disp = disp;
		#if 1
				#if 1 //240*280
				display_set_window(area->x1, area->x2, area->y1, area->y2);
		    #else
				display_set_window(area->x1, area->x2, area->y1 -20, area->y2 -20);
				#endif
				display_update((area->x2+1-area->x1 /*-60*/)*(area->y2+1-area->y1 /*-40*/), (void *)color_p, my_disp_flush_done);
		    //display_wait_transfer_done();
		#endif
			  //display_wait_transfer_done();
    lv_disp_flush_ready(last_disp);
	#endif
}

static void my_touchpad_read(struct _lv_indev_drv_t * indev, lv_indev_data_t * data)
{
    uint8_t buffer[8];
    
		 cst816_read_bytes(0x00,buffer,8); 
    //touchpad_read_data_raw(buffer, 8);
//    data->state = (buffer[2] != 0) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
	   data->state = (buffer[2] == 1) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
    if(data->state == LV_INDEV_STATE_PR) {
        data->point.x = ((buffer[3]&0x0f)<<8) | buffer[4];
        data->point.y = ((buffer[5]&0x0f)<<8) | buffer[6];
			printf("x:%d y:%d\r\n ",data->point.x ,data->point.y);
			
    }
}

struct_Timer_t Timer0_Handle;

__attribute__((section("ram_code"))) void timer0_isr(void)
{
    timer_int_clear(Timer0);
    lv_tick_inc(LV_TICK_COUNT);
    //printf("%s\r\n",__FUNCTION__,__LINE__);
}

__attribute__((section("ram_code"))) void timer1_isr(void)
{
	  
    uint32_t tick;
    timer_int_clear(Timer1);
    timer_stop(Timer1);

    tick = lv_timer_handler();
    timer_init(Timer1, system_get_clock_config()*1000*tick, TIMER_DIV_NONE);
    timer_start(Timer1);
	  
}

static void lv_schedule_timer_handler(void *arg)
{
    lv_timer_handler();
}



void gui_main(void)
{
	cst816_init();
	
	//touchpad_init(NULL);
  display_init();
  #if 1			
	//调用函数接口定义
	#define GUI_Flash_Read                IC_W25Qxx_Read_Quad_DMA_Output  //读取flash接口数据
	#define GUI_Wait_LCD_Transfer_Comlte  display_wait_transfer_done      //等待LCD	传输完成
	#define GUI_Set_LCD_Window            display_set_window              //设置显示窗口
	#define GUI_Display_Update            display_update                  
						
	
	extern  uint8_t time06_nackground_map[];
	//uint16_t *display1=(uint16_t *)(0x22000000);
	uint16_t *display2=(uint16_t *)(0x22000000+3*240*240*2);
		//鎷疯礉psram鍥剧墖
		//memset((void*)(display1),0x00,240*240*2);
	memcpy((void*)(display2),time06_nackground_map,240*280*2);


	GUI_Set_LCD_Window(0, 240-1, 0, 280-1);         
	GUI_Display_Update(240*280,(uint16_t *)(display2),NULL);    
	GUI_Wait_LCD_Transfer_Comlte();
	#endif
	lv_init();
  /*Initialize `disp_buf` with the buffer(s) */
	
		#if 1 
		lv_disp_draw_buf_init(&disp_buf, (void *)0x22000000,(void *)(0x22000000+LV_HOR_RES_MAX * LV_VER_RES_MAX*2), LV_HOR_RES_MAX * LV_VER_RES_MAX); 
    //lv_disp_draw_buf_init(&disp_buf, (void *)0x22000000,NULL/*0x22050000*//*(void *)(0x22000000+LV_HOR_RES_MAX * LV_VER_RES_MAX*2)*/, LV_HOR_RES_MAX * LV_VER_RES_MAX);    /*Initialize the display buffer*/
		#endif
	
    /* Implement and register a function which can copy the rendered image to an area of your display */
    static lv_disp_drv_t disp_drv;               /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);          /*Basic initialization*/
    disp_drv.flush_cb = my_disp_flush;    /*Set your driver function*/
    disp_drv.draw_buf =  &disp_buf;        /*Assign the buffer to the display*/
    disp_drv.hor_res = LV_HOR_RES_MAX;
    disp_drv.ver_res = LV_VER_RES_MAX;
    disp_drv.full_refresh = 0;
    lv_disp_drv_register(&disp_drv);      /*Finally register the driver*/
	
    /* Implement and register a function which can read an input device. E.g. for a touch pad */
    static lv_indev_drv_t indev_drv;                  /*Descriptor of a input device driver*/
    lv_indev_drv_init(&indev_drv);             /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

		GLOBAL_INT_START();
	  __SYSTEM_TIMER_CLK_ENABLE();
 
    timer_init(Timer0, system_get_clock_config()*1000*LV_TICK_COUNT, TIMER_DIV_NONE);
    timer_start(Timer0);
    NVIC_SetPriority(TIMER0_IRQn, 5);
    NVIC_EnableIRQ(TIMER0_IRQn);

//    timer_init(Timer1, system_get_clock_config()*1000*100, TIMER_DIV_NONE);
//    timer_start(Timer1);
//    NVIC_SetPriority(TIMER1_IRQn, 6);
//    NVIC_EnableIRQ(TIMER1_IRQn);
		
		os_timer_init(&lv_schedule_timer, lv_schedule_timer_handler, NULL);
    os_timer_start(&lv_schedule_timer, 10, true);
		
//	  lv_obj_t *obj =lv_obj_create(lv_scr_act());	  
//  	lv_obj_set_style_bg_color(obj, lv_color_make(0xff,0x00,0xff), 0);
//	  lv_obj_set_size(obj,100,100);
//  	lv_obj_center(obj);

		#include "window_manager.h"
		//init display menu
		window_manager_init();
		//lv_demo_benchmark();
		

}

